////////////////////////
//  GOD ENGINE BODY  //
//////////////////////
/*##############################
# Version:      0.9 Beta
#
# Description:  Low-level implementation of God Engine
#
# Credits:      Godplex
#               Daxter (for original idea and a bit of his code)
#
# Notes:        You shouldn't mess with this unless you intend to
#               modify some low-levl aspect of the way God Engine
#               functions. Everything you need to know to use
#               the API is conveniently documented in the header
#               file (GodEngineH.txt) and any globals you may want
#               to change are declared there.
#
# Features:     - Gathers resources based on desire
#               ^- Will water fields if necessary
#               - Puts out fires
#               - Regenerates mana based on town population
#               - Constructs new buildings
#               - (Disabled) Repairs damaged buildings
#
###      CONVENTIONS USED      ###
# - Public members prefix:  ge[Identifier]
#  ^- ARE for use outside GodEngine.txt
# - Private members prefix: ge_[Identifier]
#  ^- ARE NOT for use outside GodEngine.txt
# - PascalCase params, camelCase locals, prefix globals, GE_CAPS_AND_PREFIX global-constants & enums
#  ^- Reference params prefix with "r" (ex. rMyReferenceParam)
#  ^- Non-reference params must be stored in local variable of same name
#       but different casing (ex. myByValParam = MyByValParam)
# - Methods return values via reference paramaters with the prefix o
#  ^- (ex. geMyMethod(oMethodOutput))
# - Public methods must be fail-safe to invalid inputs
#  ^- Validity checks needed in all public members
#  ^- Data is assumed valid in private members
#
###      FILES      ###
# GodEngineH.txt - This is the header file. Everything you need to make
#                  full use of the API can be found here.
#                ^- Public globals, public enums, and documentation
#                   of public scripts goes here.
#
# GodEngine.txt  - This is the body/implementation file. All the cool,
#                  behind-the-scenes stuff happens here. ONLY look in
#                  this file if you are interested in seeing the core
#                  implementation (not needed for API use,) or if you
#                  want to gawk at my genius ;)
#                ^- ge_[anything] goes here
# 
#
### WARNING ###
# Passing paramaters ByVal (that is, storing them in local variable)
# does not prevent them from being modified when the local variable is
# modified... it PROBABLY depends on whether the object is a pointer
# or a value, but how to tell?
##############################
*/

/*
###   TODO LIST   ###
# - Throw stuff
*/

// God Engine Private Globals (oxymoron? heh)
global ge_NextHandle = 0 // is incremented by geGetNewGodHandle
global ge_MaxGodHandles = 9 // Needs to be same as max array index on God data
global ge_GodCommand[9]
global ge_GodCommandParam1[9]
global ge_GodCommandParam2[9]
global ge_GodCommandParam3[9]
global ge_TypeInHand[9]
global ge_QuantityInHand[9]
global ge_ObjectInHand[9]
global ge_HomeTown[9]
global ge_Player[9]
global ge_Mana[9]
global ge_ManaPerSecond[9]


////////////////////////////
//   GOD ENGINE ENUMS   ///
//////////////////////////
//    Do NOT modify.    //
/////////////////////////

// God Command Enum
global GE_COM_DELETE_GOD = 0
global GE_COM_NOTHING = 1
global GE_COM_COMMAND_COMPLETE = 2
global GE_COM_ERROR = 3
global GE_COM_MOVE_TO_OBJECT = 4
global GE_COM_PICKUP_RESOURCE = 5
global GE_COM_DROP_IN_STOREHOUSE = 6
global GE_COM_THROW_MIRACLE = 7
global GE_COM_GOD_BUILD = 8
global GE_COM_CREATE_DISCIPLE = 9
global GE_COM_REMOVE_DISCIPLE = 10
global GE_COM_THROW_OBJECT_AT_OBJECT = 11

// Bool Type
// global GE_TRUE = 1
// global GE_FALSE = 0

// Resource Type Enum
global GE_HT_EMPTY = 0
global GE_HT_FOOD = 1
global GE_HT_WOOD = 2
global GE_HT_ORE = 3
global GE_HT_OTHER = 4

// Miracle Type Enum
global GE_MIRACLE_TYPE_NONE                               =  0
global GE_MIRACLE_TYPE_HEAL                               =  1
global GE_MIRACLE_TYPE_LIFE                               =  2 // Does not work
global GE_MIRACLE_TYPE_DECAY                              =  3 // Does not work
global GE_MIRACLE_TYPE_DEATH                              =  4 // Does not work
global GE_MIRACLE_TYPE_FIRE                               =  5
global GE_MIRACLE_TYPE_LAVA                               =  6 // Does not work
global GE_MIRACLE_TYPE_TREMOR                             =  7 // Does not work
global GE_MIRACLE_TYPE_METEOR                             =  8
global GE_MIRACLE_TYPE_WIND                               =  9 // Does not work
global GE_MIRACLE_TYPE_TORNADO                            =  10
global GE_MIRACLE_TYPE_WATER                              =  11
global GE_MIRACLE_TYPE_STORM                              =  12
global GE_MIRACLE_TYPE_LAST                               =  13

// Disciple Type Enum
global GE_VILLAGER_DISCIPLE_NONE                          =  0
global GE_VILLAGER_DISCIPLE_FARMER                        =  1
global GE_VILLAGER_DISCIPLE_FORESTER                      =  2
global GE_VILLAGER_DISCIPLE_FISHERMAN                     =  3 // Does not work
global GE_VILLAGER_DISCIPLE_BUILDER                       =  4
global GE_VILLAGER_DISCIPLE_BREEDER                       =  5
global GE_VILLAGER_DISCIPLE_PROTECTION                    =  6 // Does not work
global GE_VILLAGER_DISCIPLE_MISSIONARY                    =  7 // Does not work
global GE_VILLAGER_DISCIPLE_CRAFTSMAN                     =  8 // Does not work
global GE_VILLAGER_DISCIPLE_TRADER                        =  9 // Does not work
global GE_VILLAGER_DISCIPLE_CHANGE_HOUSE                  =  10
global GE_VILLAGER_DISCIPLE_WORSHIP                       =  11
global GE_VILLAGER_DISCIPLE_PROTESTOR                     =  12 // Does not work
global GE_VILLAGER_DISCIPLE_RESEARCHER                    =  13 // Does not work
global GE_VILLAGER_DISCIPLE_MINER                         =  14
global GE_VILLAGER_DISCIPLE_PILGRIM                       =  15 // Does not work
global GE_VILLAGER_DISCIPLE_REFINER                       =  16

/////////////////////////////
//  GOD ENGINE SCRIPTS   ///
///////////////////////////
// These methods act as primitives for
// creatin custom AI behavoirs.
//////////////////////////

// # PUBLIC METHODS
// Accessors & anything that returns a value
// (Note: Set methods don't return a value)
define script geGetNewGodHandle(rHomeTown)
define script geGetTypeInHand(GodHandle)
define script geGetQuantityInHand(GodHandle)
define script geGetHomeTown(GodHandle)
define script geGetMana(GodHandle)
define script geSetMana(GodHandle,NewValue)
define script geGetManaPerSecond(GodHandle)
define script geSetManaPerSecond(GodHandle,NewValue)
// Actions
define script geDeleteGod(GodHandle)
define script geMoveToObject(GodHandle,rObject)
define script gePickupResource(GodHandle,rResourceObject,rResourceType,ResourceQuantity)
define script geDropInStorehouse(GodHandle,rStorehouse,ResourceQuantity)
define script geThrowMiracle(GodHandle, MiracleType, rTargetObject)
define script geThrowObjectAtObject(GodHandle, rThrowObject, rTargetObject)
define script geGodBuild(GodHandle,rBuilding,ResourceGatherRadius)
define script geCreateDisciple(GodHandle,DiscipleType)
define script geRemoveDisciple(GodHandle,DiscipleType,TownRadius)

// # PRIVATE METHODS
define script ge_GodLoop(GodHandle,rGodInstance)
define script ge_MoveToObject(GodHandle,rGodInstance,rObject)
define script ge_MoveToRadiusAltitude(GodHandle,rGodInstance,rTargetObject,Radius,Altitude)
define script ge_PickupResource(GodHandle,rGodInstance,rResourceObject,ResourceType,ResourceQuantity)
define script ge_DropInStorehouse(GodHandle,rGodInstance,rStorehouse,ResourceQuantity)
define script ge_ThrowMiracle(GodHandle, rGodInstance, MiracleType, rTargetObject)
define script ge_ThrowObjectAtObject(GodHandle, rGodInstance, rThrowObject, rTargetObject)
define script ge_GodBuild(GodHandle,rGodInstance,rBuilding,ResourceGatherRadius)
define script ge_GoGetOre(GodHandle,rGodInstance,AmountNeeded,ResourceGatherRadius)
define script ge_GoGetWood(GodHandle,rGodInstance,AmountNeeded,ResourceGatherRadius)
define script ge_CreateDisciple(rGodInstance,GodHandle,DiscipleType)
define script ge_RemoveDisciple(rGodInstance,GodHandle,DiscipleType,TownRadius)
define script ge_ChargeMana(GodHandle)


/////////////////////////////
//   GE VISUAL SCRIPTS   ///
///////////////////////////
// These methods determine how the god
// will look. They may be moved to a
// different document at a later time.
//////////////////////////

define script ge_VisualFoodUp(rGodInstance,Time)



// ## GOD ENGINE SCRIPTS IMPLEMENTATION ##
// # PUBLIC METHODS #

begin script geGetNewGodHandle(rHomeTown)
	rGodInstance = 0
	rGodVisualEffect = 0
	godHandle = 0
start
	// Returns -1 if there are no valid handles to be assigned to new god
	if ge_NextHandle <= ge_MaxGodHandles and rHomeTown exists
		godHandle = ge_NextHandle
		ge_NextHandle = ge_NextHandle + 1
		
		rGodInstance = create with angle geAvatarAngle and scale geAvatarScale geAvatarScriptType geAvatarObjectType at {rHomeTown}
		rGodVisualEffect = create visual effect geAvatarVisualEffect on rGodInstance time -1

		enable rGodInstance moveable
		enable rGodInstance indestructible
		disable rGodInstance pickup
		disable rGodInstance can be fisted
		ALTITUDE of rGodInstance = geGodAltitude
		SCRIPT_OBJECT_PROPERTY_TYPE_DENSITY of rGodInstance = 0.0
		// TODO: NEED WAY TO SET PHYSICS PROPERTIES SO HAS NO WEIGHT
		
		ge_GodCommand[godHandle] = GE_COM_NOTHING
		ge_GodCommandParam1[godHandle] = 0
		ge_GodCommandParam2[godHandle] = 0
		ge_GodCommandParam3[godHandle] = 0
		ge_TypeInHand[godHandle] = GE_HT_EMPTY
		ge_QuantityInHand[godHandle] = 0
		ge_ObjectInHand[godHandle] = 0
		ge_HomeTown[godHandle] = rHomeTown
		ge_Player[godHandle] = get SCRIPT_OBJECT_PROPERTY_TYPE_PLAYER of rHomeTown // TODO: Make sure this works!
		ge_Mana[godHandle] = geGodStartingMana
		ge_ManaPerSecond[godHandle] = geGodStartingManaPerSecond
		
		run background script ge_GodLoop(godHandle,rGodInstance)
		run background script ge_ChargeMana(godHandle)
	else
		godHandle = -1
	end if
	
	//oGodHandle = godHandle
	run script geReturn(godHandle)
end script geGetNewGodHandle


begin script geGetTypeInHand(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		run script geReturn(ge_TypeInHand[godHandle])
	end if
end script geGetTypeInHand


begin script geGetQuantityInHand(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		run script geReturn(ge_QuantityInHand[godHandle])
	end if
end script geGetQuantityInHand


begin script geGetHomeTown(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		run script geReturn(ge_HomeTown[godHandle])
	end if
end script geGetHomeTown


begin script geGetMana(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		run script geReturn(ge_Mana[godHandle])
	end if
end script geGetMana

begin script geSetMana(GodHandle,NewValue)
	godHandle = GodHandle
	newValue = NewValue
start
	if 0 <= godHandle and godHandle < ge_NextHandle and not newValue exists
		ge_Mana[godHandle] = newValue
	end if
end script geSetMana


begin script geGetManaPerSecond(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		run script geReturn(ge_ManaPerSecond[godHandle])
	end if
end script geGetManaPerSecond

begin script geSetManaPerSecond(GodHandle,NewValue)
	godHandle = GodHandle
	newValue = NewValue
start
	if 0 <= godHandle and godHandle < ge_NextHandle and not newValue exists
		ge_ManaPerSecond[godHandle] = newValue
	end if
end script geSetManaPerSecond


begin script geDeleteGod(GodHandle)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle
		ge_GodCommand[godHandle] = GE_COM_DELETE_GOD
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
	end if
end script geDeleteGod


begin script geMoveToObject(GodHandle,rObject)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle and rObject exists
		ge_GodCommandParam1[godHandle] = rObject
		ge_GodCommand[godHandle] = GE_COM_MOVE_TO_OBJECT
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geMoveToObject


begin script gePickupResource(GodHandle,rResourceObject,ResourceType,ResourceQuantity)
	godHandle = GodHandle
	resourceType = ResourceType
	resourceQuantity = ResourceQuantity
start
	// The following line is a doozy, but the language does not allow mult-line if statements.
	// Basically, it checks: godHandle valid? Resource object exist?
	// Requested resource match the object's resource type?
	if 0 <= godHandle and godHandle < ge_NextHandle and rResourceObject exists and ((resourceType == GE_HT_FOOD and 0 < get resource RESOURCE_TYPE_FOOD in rResourceObject) or (resourceType == GE_HT_WOOD and 0 < get resource RESOURCE_TYPE_WOOD in rResourceObject) or (resourceType == GE_HT_ORE and 0 < get resource RESOURCE_TYPE_ORE in rResourceObject))
			ge_GodCommandParam1[godHandle] = rResourceObject
			ge_GodCommandParam2[godHandle] = resourceType
			ge_GodCommandParam3[godHandle] = resourceQuantity
			ge_GodCommand[godHandle] = GE_COM_PICKUP_RESOURCE
			wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
			ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script gePickupResource


begin script geDropInStorehouse(GodHandle,rStorehouse,ResourceQuantity)
	godHandle = GodHandle
	resourceQuantity = ResourceQuantity
start
	if 0 <= godHandle and godHandle < ge_NextHandle and rStorehouse exists
		ge_GodCommandParam1[godHandle] = rStorehouse
		ge_GodCommandParam2[godHandle] = resourceQuantity
		ge_GodCommand[godHandle] = GE_COM_DROP_IN_STOREHOUSE
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geDropInStorehouse


begin script geThrowMiracle(GodHandle, MiracleType, rTargetObject)
	godHandle = GodHandle
	miracleType = MiracleType
start
	if 0 <= godHandle and godHandle < ge_NextHandle and rTargetObject exists and GE_MIRACLE_TYPE_NONE < miracleType and miracleType < GE_MIRACLE_TYPE_LAST
		ge_GodCommandParam1[godHandle] = miracleType
		ge_GodCommandParam2[godHandle] = rTargetObject
		ge_GodCommand[godHandle] = GE_COM_THROW_MIRACLE
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geThrowMiracle


begin script geThrowObjectAtObject(GodHandle, rThrowObject, rTargetObject)
	godHandle = GodHandle
start
	if 0 <= godHandle and godHandle < ge_NextHandle and rThrowObject exists and rTargetObject exists
		ge_GodCommandParam1[godHandle] = rThrowObject
		ge_GodCommandParam2[godHandle] = rTargetObject
		ge_GodCommand[godHandle] = GE_COM_THROW_OBJECT_AT_OBJECT
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geThrowObjectAtObject


begin script geGodBuild(GodHandle,rBuilding,ResourceGatherRadius)
	godHandle = GodHandle
	resourceGatherRadius = ResourceGatherRadius
start
	if 0 <= godHandle and godHandle < ge_NextHandle and rBuilding exists and SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding < 1.0
		ge_GodCommandParam1[godHandle] = rBuilding
		ge_GodCommandParam2[godHandle] = resourceGatherRadius
		ge_GodCommand[godHandle] = GE_COM_GOD_BUILD
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geGodBuild


begin script geCreateDisciple(GodHandle,DiscipleType)
	godHandle = GodHandle
	discipleType = DiscipleType
start
	if 0 <= godHandle and godHandle < ge_NextHandle and GE_VILLAGER_DISCIPLE_FARMER <= discipleType and discipleType <= GE_VILLAGER_DISCIPLE_REFINER
		ge_GodCommandParam1[godHandle] = discipleType
		ge_GodCommand[godHandle] = GE_COM_CREATE_DISCIPLE
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geCreateDisciple


begin script geRemoveDisciple(GodHandle,DiscipleType,TownRadius)
	godHandle = GodHandle
	discipleType = DiscipleType
	townRadius = TownRadius
start
	if 0 <= godHandle and godHandle < ge_NextHandle and GE_VILLAGER_DISCIPLE_FARMER <= discipleType and discipleType <= GE_VILLAGER_DISCIPLE_REFINER and 0 < TownRadius
		ge_GodCommandParam1[godHandle] = discipleType
		ge_GodCommandParam2[godHandle] = townRadius
		ge_GodCommand[godHandle] = GE_COM_REMOVE_DISCIPLE
		wait until ge_GodCommand[godHandle] == GE_COM_COMMAND_COMPLETE
		ge_GodCommand[godHandle] = GE_COM_NOTHING
	end if
end script geRemoveDisciple


// ## GOD ENGINE SCRIPTS IMPLEMENTATION ##
// # PRIVATE METHODS #

begin script ge_GodLoop(GodHandle,rGodInstance)
	godHandle = GodHandle
start
	while ge_GodCommand[godHandle] != GE_COM_DELETE_GOD
		if ge_GodCommand[godHandle] == GE_COM_MOVE_TO_OBJECT
			run script ge_MoveToObject(godHandle,rGodInstance,ge_GodCommandParam1[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_PICKUP_RESOURCE
			run script ge_PickupResource(godHandle,rGodInstance,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle],ge_GodCommandParam3[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_DROP_IN_STOREHOUSE
			run script ge_DropInStorehouse(godHandle,rGodInstance,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_THROW_MIRACLE
			run script ge_ThrowMiracle(godHandle,rGodInstance,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_GOD_BUILD
			run script ge_GodBuild(godHandle,rGodInstance,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_CREATE_DISCIPLE
			run script ge_CreateDisciple(rGodInstance,godHandle,ge_GodCommandParam1[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_REMOVE_DISCIPLE
			run script ge_RemoveDisciple(rGodInstance,godHandle,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		elsif ge_GodCommand[godHandle] == GE_COM_THROW_OBJECT_AT_OBJECT
			run script ge_ThrowObjectAtObject(godHandle,rGodInstance,ge_GodCommandParam1[godHandle],ge_GodCommandParam2[godHandle])
			ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
		end if
	end while

	delete rGodInstance
	ge_GodCommand[godHandle] = GE_COM_COMMAND_COMPLETE
end script ge_GodLoop



// I really wish there was a more elegant way to do this...
begin script ge_MoveToObject(GodHandle,rGodInstance,rTargetObject)
	godHandle = GodHandle
start
	while {rGodInstance} not near {rTargetObject} radius geArrivalRadius
		ALTITUDE of rGodInstance = geGodAltitude
		if ge_ObjectInHand[godHandle] exists
			set ge_ObjectInHand[godHandle] position to {rGodInstance}
			ALTITUDE of ge_ObjectInHand[godHandle] = ALTITUDE of rGodInstance
		end if
		set rGodInstance velocity heading ({rTargetObject} + {0,(geGodAltitude + 1.0),0}) speed geGodSpeed
		wait 0.05 seconds
	end while
	
	set rGodInstance position to {rTargetObject}
	ALTITUDE of rGodInstance = geGodAltitude
	if ge_ObjectInHand[godHandle] exists
		ALTITUDE of ge_ObjectInHand[godHandle] = ALTITUDE of rGodInstance
	end if
end script ge_MoveToObject

/*
begin script ge_MoveToRadiusAltitude(GodHandle,rGodInstance,rTargetObject,Radius,Altitude)
	godHandle = GodHandle
	myRadius = Radius
	targetAltitude = Altitude
	currentAltitude = ALTITUDE of rGodInstance
	altitudeChange = (targetAltitude - currentAltitude) * 0.05
start
	while {rGodInstance} not near {rTargetObject} radius myRadius
		if not 0.1 < (targetAltitude - currentAltitude) or not (targetAltitude - currentAltitude) < -0.1
			currentAltitude += altitudeChange
		end if
		ALTITUDE of rGodInstance = currentAltitude
		if ge_ObjectInHand[godHandle] exists
			set ge_ObjectInHand[godHandle] position to {rGodInstance}
			ALTITUDE of ge_ObjectInHand[godHandle] = ALTITUDE of rGodInstance
		end if
		set rGodInstance velocity heading ({rTargetObject} + {0,(targetAltitude + 1.0),0}) speed geGodSpeed
		wait 0.01 seconds
	end while

	ALTITUDE of rGodInstance = targetAltitude
	if ge_ObjectInHand[godHandle] exists
		ALTITUDE of ge_ObjectInHand[godHandle] = ALTITUDE of rGodInstance
	end if
end script ge_MoveToRadiusAltitude
*/


begin script ge_MoveToRadiusAltitude(GodHandle,rGodInstance,rTargetObject,Radius,Altitude)
	myRadius = Radius
	targetAltitude = Altitude
	currentAltitude = ALTITUDE of rGodInstance
	altitudeChange = (targetAltitude - currentAltitude) * 0.05
start
	while {rGodInstance} not near {rTargetObject} radius myRadius
		if not 0.1 < (targetAltitude - currentAltitude) or not (targetAltitude - currentAltitude) < -0.1
			currentAltitude += altitudeChange
		end if
		ALTITUDE of rGodInstance = currentAltitude
		set rGodInstance velocity heading ({rTargetObject} + {0,(targetAltitude + 1.0),0}) speed geGodSpeed
		wait 0.01 seconds
	end while

	ALTITUDE of rGodInstance = targetAltitude
end script ge_MoveToRadiusAltitude



// Passing in a resourceQuantity greater than that available in ResourceObject will cause it to take
// as much as it can. Passing in -1 will also cause it to take all ResourceType in ResourceObject.
// Also, gathering a resourse with a different resourse type in hand will cause the first type to disappear.
begin script ge_PickupResource(GodHandle,rGodInstance,rResourceObject,ResourceType,ResourceQuantity)
	godHandle = GodHandle
	resourceQuantity = ResourceQuantity
	resourceType = ResourceType
	resourceGatherTime = 0 // resourceQuantity / (geGodResourceGatherSpeed * 10.0)
	resourceAvailable = 0
start
	run script ge_MoveToObject(godHandle,rGodInstance,rResourceObject)

	// If holding a different resource than trying to pick up, first resource gets deleted
	if ge_TypeInHand[godHandle] != resourceType
		ge_QuantityInHand[godHandle] = 0
		ge_TypeInHand[godHandle] = resourceType
	end if

	ALTITUDE of rGodInstance = gePickupResourceAltitude
	
	if resourceType == GE_HT_FOOD
		resourceAvailable = get resource RESOURCE_TYPE_FOOD in rResourceObject
		if resourceQuantity < 0 or resourceAvailable < resourceQuantity
			resourceQuantity = resourceAvailable
			resourceGatherTime = resourceQuantity / (geGodResourceGatherSpeed * 10.0)
		end if
		
		run background script ge_VisualFoodUp(rGodInstance, resourceGatherTime)
		while resourceQuantity > geGodResourceGatherSpeed
			ge_QuantityInHand[godHandle] += geGodResourceGatherSpeed
			remove resource RESOURCE_TYPE_FOOD geGodResourceGatherSpeed from rResourceObject
			resourceQuantity = resourceQuantity - geGodResourceGatherSpeed
			wait 0.1 seconds
		end while
		ge_QuantityInHand[godHandle] += resourceQuantity
		remove resource RESOURCE_TYPE_FOOD resourceQuantity from rResourceObject
		
		
	elsif resourceType == GE_HT_WOOD
		resourceAvailable = get resource RESOURCE_TYPE_WOOD in rResourceObject
		if resourceQuantity < 0 or resourceAvailable < resourceQuantity
			resourceQuantity = resourceAvailable
			resourceGatherTime = resourceQuantity / (geGodResourceGatherSpeed * 10.0)
		end if
		
		run background script ge_VisualFoodUp(rGodInstance, resourceGatherTime)	// TODO: MAKE ge_VisualWoodUp
		while resourceQuantity > geGodResourceGatherSpeed
			ge_QuantityInHand[godHandle] += geGodResourceGatherSpeed
			remove resource RESOURCE_TYPE_WOOD geGodResourceGatherSpeed from rResourceObject
			resourceQuantity = resourceQuantity - geGodResourceGatherSpeed
			wait 0.1 seconds
		end while
		ge_QuantityInHand[godHandle] += resourceQuantity
		remove resource RESOURCE_TYPE_WOOD resourceQuantity from rResourceObject
		
		
	elsif resourceType == GE_HT_ORE
		resourceAvailable = get resource RESOURCE_TYPE_ORE in rResourceObject
		if resourceQuantity < 0 or resourceAvailable < resourceQuantity
			resourceQuantity = resourceAvailable
			resourceGatherTime = resourceQuantity / (geGodResourceGatherSpeed * 10.0)
		end if
		
		run background script ge_VisualFoodUp(rGodInstance, resourceGatherTime)	// TODO: MAKE ge_VisualOreUp
		while resourceQuantity > geGodResourceGatherSpeed
			ge_QuantityInHand[godHandle] += geGodResourceGatherSpeed
			remove resource RESOURCE_TYPE_ORE geGodResourceGatherSpeed from rResourceObject
			resourceQuantity = resourceQuantity - geGodResourceGatherSpeed
			wait 0.1 seconds
		end while
		ge_QuantityInHand[godHandle] += resourceQuantity
		remove resource RESOURCE_TYPE_ORE resourceQuantity from rResourceObject
	end if
	
	if ge_QuantityInHand[godHandle] <= 0
		ge_TypeInHand[godHandle] = GE_HT_EMPTY
	end if
	ALTITUDE of rGodInstance = geGodAltitude
end script ge_PickupResource


begin script ge_DropInStorehouse(GodHandle,rGodInstance,rStorehouse,ResourceQuantity)
	godHandle = GodHandle
	resourceQuantity = ResourceQuantity
start
	run script ge_MoveToObject(godHandle,rGodInstance,rStorehouse)
	
	// Passing -1 or amount greater than held will both dump full quantity
	if resourceQuantity < 0
		resourceQuantity = ge_QuantityInHand[godHandle]
	elsif resourceQuantity > ge_QuantityInHand[godHandle]
		resourceQuantity = ge_QuantityInHand[godHandle]
	end if
	
	if ge_TypeInHand[godHandle] == GE_HT_FOOD
		add resource RESOURCE_TYPE_FOOD resourceQuantity to rStorehouse
		ge_QuantityInHand[godHandle] -= resourceQuantity
		// TODO: PLAY A SOUND HERE
	elsif ge_TypeInHand[godHandle] == GE_HT_WOOD
		add resource RESOURCE_TYPE_WOOD resourceQuantity to rStorehouse
		ge_QuantityInHand[godHandle] -= resourceQuantity
		// TODO: PLAY A SOUND HERE
	elsif ge_TypeInHand[godHandle] == GE_HT_ORE
		add resource RESOURCE_TYPE_ORE resourceQuantity to rStorehouse
		ge_QuantityInHand[godHandle] -= resourceQuantity
		// TODO: PLAY A SOUND HERE
	end if
	
	set rGodInstance position to {rStorehouse}
	ALTITUDE of rGodInstance = geGodAltitude
end script ge_DropInStorehouse


begin script ge_ThrowMiracle(GodHandle, rGodInstance, MiracleType, rTargetObject)
	godHandle = GodHandle
	miracleType = MiracleType
	newMiracle = 0
start
	if miracleType > GE_MIRACLE_TYPE_NONE and miracleType < GE_MIRACLE_TYPE_LAST
		run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,rTargetObject,geGodThrowRadius,geGodThrowAltitude)
		//SCRIPT_OBJECT_PROPERTY_TYPE_YPOS of rGodInstance = geGodThrowAltitude
		wait 1 seconds
		if miracleType == GE_MIRACLE_TYPE_HEAL and ge_Mana[godHandle] >= geManaCostHeal
			ge_Mana[godHandle] -= geManaCostHeal
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_HEAL from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_LIFE and ge_Mana[godHandle] >= geManaCostLife
			ge_Mana[godHandle] -= geManaCostLife
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_LIFE from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_DECAY and ge_Mana[godHandle] >= geManaCostDecay
			ge_Mana[godHandle] -= geManaCostDecay
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_DECAY from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_DEATH and ge_Mana[godHandle] >= geManaCostDeath
			ge_Mana[godHandle] -= geManaCostDeath
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_DEATH from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_FIRE and ge_Mana[godHandle] >= geManaCostFire
			ge_Mana[godHandle] -= geManaCostFire
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_FIRE from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_LAVA and ge_Mana[godHandle] >= geManaCostLava
			ge_Mana[godHandle] -= geManaCostLava
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_LAVA from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_TREMOR and ge_Mana[godHandle] >= geManaCostTremor
			ge_Mana[godHandle] -= geManaCostTremor
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_TREMOR from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_METEOR and ge_Mana[godHandle] >= geManaCostMeteor
			ge_Mana[godHandle] -= geManaCostMeteor
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_METEOR from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_WIND and ge_Mana[godHandle] >= geManaCostWind
			ge_Mana[godHandle] -= geManaCostWind
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_WIND from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_TORNADO and ge_Mana[godHandle] >= geManaCostTornado
			ge_Mana[godHandle] -= geManaCostTornado
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_TORNADO from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_WATER and ge_Mana[godHandle] >= geManaCostWater
			ge_Mana[godHandle] -= geManaCostWater
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_WATER from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		elsif miracleType == GE_MIRACLE_TYPE_STORM and ge_Mana[godHandle] >= geManaCostStorm
			ge_Mana[godHandle] -= geManaCostStorm
			newMiracle = make player ge_Player[godHandle] throw miracle MIRACLE_TYPE_STORM from ({rGodInstance} + {0, -3.0, 0}) heading (({rTargetObject} + {0,geThrowArc,0}) - {rGodInstance})
		end if
		SCRIPT_OBJECT_PROPERTY_TYPE_SPEED of newMiracle = geThrowSpeed
		wait 1 seconds
		SCRIPT_OBJECT_PROPERTY_TYPE_YPOS of rGodInstance = geGodAltitude
	end if
end script ge_ThrowMiracle


// BROKEN
//  - Not calculating trajectories properly. I'm sure that density is a factor in wind resistance... I need
//    to experiment to figure out the exact physical properties of the world, and prepare a better formula.
begin script ge_ThrowObjectAtObject(GodHandle, rGodInstance, rThrowObject, rTargetObject)
	godHandle = GodHandle
	throwObjectAltitudeMod = SCRIPT_OBJECT_PROPERTY_TYPE_ACTUAL_HEIGHT of rThrowObject * 0.8
	velocityYmod = 0 // set to 45 degrees
	// distanceOffTarget = 0.0
	// lastDistanceOffTarget = 0.0
	// throwDistance = get distance from {rThrowObject} to {rTargetObject}
start
/*
#	God moves to object
#	God sets object position to just above itself
#	God moves within range (if necessary)
#	God calculates needed velocity and fires
#   ^- Object fires from above god to avoid knocking itself over
#   ^- 
*/
	run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,rThrowObject,geArrivalRadius,gePickUpObjectAltitude)
	ge_ObjectInHand[godHandle] = rThrowObject // TODO: Is this needed?
	
	// This will make them both move together, the object hovering above the god.
	ALTITUDE of rGodInstance = geGodAltitude
	ALTITUDE of rThrowObject = geGodAltitude + throwObjectAltitudeMod
	run background script ge_MoveToRadiusAltitude(godHandle,rThrowObject,rTargetObject,geGodThrowRadius,(geGodAltitude + throwObjectAltitudeMod))
	run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,rTargetObject,geGodThrowRadius,geGodAltitude)

	// Find velocity needed
	/*
	distanceOffTarget = get distance from landing position of rThrowObject velocity heading {rTargetObject} + {0,velocityYmod,0} speed geThrowSpeed to {rTargetObject}
	lastDistanceOffTarget = distanceOffTarget + 1
	while 5.0 < distanceOffTarget and distanceOffTarget < lastDistanceOffTarget
		velocityYmod += 1.0
		lastDistanceOffTarget = distanceOffTarget
		distanceOffTarget = get distance from landing position of rThrowObject velocity heading {rTargetObject} + {0,velocityYmod,0} speed geThrowSpeed to {rTargetObject}
	end while
	*/
	velocityYmod = (get distance from {rThrowObject} to {rTargetObject}) * 1.5
	set rThrowObject velocity heading {rTargetObject} + {0,velocityYmod,0} speed (get distance from {rThrowObject} to {rTargetObject}) * 1.2 // * SCRIPT_OBJECT_PROPERTY_TYPE_DENSITY of rThrowObject
	// set rThrowObject target {rTargetObject} time 2 // (get distance from {rThrowObject} to {rTargetObject}) * 0.1
	ge_ObjectInHand[godHandle] = 0
	ALTITUDE of rGodInstance = geGodAltitude
	wait 2 seconds
end script ge_ThrowObjectAtObject


begin script ge_GodBuild(GodHandle,rGodInstance,rBuilding,ResourceGatherRadius)
	godHandle = GodHandle
	resourceGatherRadius = ResourceGatherRadius
	builtRatio = SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding
	myStorehouse = get building ABODE_NUMBER_STORAGE_PIT in ge_HomeTown[godHandle] min built 1.0
	baseOreCost = 0
	baseWoodCost = 0
	finalOreCost = 0
	finalWoodCost = 0
	woodBuildTime = 0
	buildRate = 0
start
	/* // I think the health property is not ratio, but total int. Need to look into this maybe fix repair.
	      Remember to add health check back into the public method if this is re-enabled
	if SCRIPT_OBJECT_PROPERTY_TYPE_HEALTH of rBuilding < 1.0
		SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding = SCRIPT_OBJECT_PROPERTY_TYPE_HEALTH of rBuilding
		builtRatio = SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding
		SCRIPT_OBJECT_PROPERTY_TYPE_HEALTH of rBuilding = 1.0
	end if
	*/

	// Get base wood cost of building type
	run script bcGetOreCostOf(rBuilding)
	baseOreCost = bcReturnVal
	run script bcUnlockReturn
	run script bcGetWoodCostOf(rBuilding)
	baseWoodCost = bcReturnVal
	run script bcUnlockReturn
	
	// Calculate cost to finish based on completion level
	finalOreCost = (baseOreCost * (1.0 - builtRatio)) * geGodBuildEfficiency
	finalWoodCost = (baseWoodCost * (1.0 - builtRatio)) * geGodBuildEfficiency
	
	if finalWoodCost > 0
		if not ge_TypeInHand[godHandle] == GE_HT_WOOD and not ge_TypeInHand[godHandle] == GE_HT_EMPTY
			run script ge_DropInStorehouse(godHandle,rGodInstance,myStorehouse,-1)
		end if
		run script ge_GoGetWood(godHandle,rGodInstance,finalWoodCost,resourceGatherRadius)
	end if
		
	// buildRate = amount of ratio to restore every 0.1 seconds
	buildRate = (1.0 - builtRatio) / ((finalWoodCost + finalOreCost) / geGodBuildRate)
	// woodBuildTime = number of loop intervals spent on wood
	woodBuildTime = (finalWoodCost / (finalWoodCost + finalOreCost)) * ((finalWoodCost + finalOreCost) / geGodBuildRate)
	
	run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,rBuilding,4.0,geGodBuildAltitude)

	while SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding < 1.0 and 0 < woodBuildTime
		SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding += buildRate
		woodBuildTime -= 1
		wait 0.1 seconds
	end while
	
	ge_QuantityInHand[godHandle] = 0
	ge_TypeInHand[godHandle] = GE_HT_EMPTY
	
	if finalOreCost > 0
		if not ge_TypeInHand[godHandle] == GE_HT_ORE and not ge_TypeInHand[godHandle] == GE_HT_EMPTY
			run script ge_DropInStorehouse(godHandle,rGodInstance,myStorehouse,-1)
		end if
		run script ge_GoGetOre(godHandle,rGodInstance,finalOreCost,resourceGatherRadius)
	end if
	
	run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,rBuilding,4.0,geGodBuildAltitude)
	
	while SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding < 1.0
		SCRIPT_OBJECT_PROPERTY_TYPE_BUILT_PERCENTAGE of rBuilding += buildRate
		wait 0.1 seconds
	end while
	
	ge_QuantityInHand[godHandle] = 0
	ge_TypeInHand[godHandle] = GE_HT_EMPTY
	
	ALTITUDE of rGodInstance = geGodAltitude
end script ge_GodBuild


// Fist tries storehouse, then tries ore rocks
begin script ge_GoGetOre(GodHandle,rGodInstance,AmountNeeded,ResourceGatherRadius)
	godHandle = GodHandle
	amountNeeded = AmountNeeded
	resourceGatherRadius = ResourceGatherRadius
	myStorehouse = 0
	maxStorehouseChecks = get number of type SCRIPT_OBJECT_TYPE_ABODE ABODE_NUMBER_STORAGE_PIT in ge_HomeTown[godHandle] min built 1.0
	myOreRock = 0
start
	if ge_TypeInHand[godHandle] != GE_HT_ORE
		ge_QuantityInHand[godHandle] = 0
		ge_TypeInHand[godHandle] = GE_HT_ORE
	end if
	while ge_QuantityInHand[godHandle] < amountNeeded and 0 < maxStorehouseChecks
		maxStorehouseChecks -= 1
		myStorehouse = get town ge_HomeTown[godHandle] storage pit with most RESOURCE_TYPE_ORE
		if myStorehouse exists
			run script ge_PickupResource(godHandle,rGodInstance,myStorehouse,GE_HT_ORE,amountNeeded)
		end if
	end while
	myOreRock = get SCRIPT_OBJECT_TYPE_ORE_ROCK at {ge_HomeTown[godHandle]} radius resourceGatherRadius
	while ge_QuantityInHand[godHandle] < amountNeeded and myOreRock exists
		run script ge_PickupResource(godHandle,rGodInstance,myOreRock,GE_HT_ORE,amountNeeded)
		myOreRock = get SCRIPT_OBJECT_TYPE_ORE_ROCK at {ge_HomeTown[godHandle]} radius resourceGatherRadius
	end while
end script ge_GoGetOre


// Fist tries storehouse, then tries trees
begin script ge_GoGetWood(GodHandle,rGodInstance,AmountNeeded,ResourceGatherRadius)
	godHandle = GodHandle
	amountNeeded = AmountNeeded
	resourceGatherRadius = ResourceGatherRadius
	myStorehouse = 0
	maxStorehouseChecks = get number of type SCRIPT_OBJECT_TYPE_ABODE ABODE_NUMBER_STORAGE_PIT in ge_HomeTown[godHandle] min built 1.0
	myTree = 0
start
	if ge_TypeInHand[godHandle] != GE_HT_WOOD
		ge_QuantityInHand[godHandle] = 0
		ge_TypeInHand[godHandle] = GE_HT_WOOD
	end if
	while ge_QuantityInHand[godHandle] < amountNeeded and 0 < maxStorehouseChecks
		maxStorehouseChecks -= 1
		myStorehouse = get town ge_HomeTown[godHandle] storage pit with most RESOURCE_TYPE_WOOD
		if myStorehouse exists
			run script ge_PickupResource(godHandle,rGodInstance,myStorehouse,GE_HT_WOOD,amountNeeded)
		end if
	end while
	myTree = get SCRIPT_OBJECT_TYPE_TREE at {ge_HomeTown[godHandle]} radius resourceGatherRadius
	while ge_QuantityInHand[godHandle] < amountNeeded and myTree exists
		run script ge_PickupResource(godHandle,rGodInstance,myTree,GE_HT_WOOD,amountNeeded)
		myTree = get SCRIPT_OBJECT_TYPE_TREE at {ge_HomeTown[godHandle]} radius resourceGatherRadius
	end while
end script ge_GoGetWood


begin script ge_CreateDisciple(rGodInstance,GodHandle,DiscipleType)
	godHandle = GodHandle
	discipleType = DiscipleType
	villagerToMod = 0
	randomPlace = 0
start
	while not villagerToMod exists or (discipleType == GE_VILLAGER_DISCIPLE_BREEDER and not villagerToMod is male)
		randomPlace = get random abode in town ge_HomeTown[godHandle]
		villagerToMod = get disciple VILLAGER_DISCIPLE_NONE at {randomPlace} radius 50.0
	end while
	run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,villagerToMod,geArrivalRadius,gePickupResourceAltitude)

	if discipleType == GE_VILLAGER_DISCIPLE_FARMER
		set villagerToMod disciple VILLAGER_DISCIPLE_FARMER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_FORESTER
		set villagerToMod disciple VILLAGER_DISCIPLE_FORESTER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_FISHERMAN
		set villagerToMod disciple VILLAGER_DISCIPLE_FISHERMAN with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_BUILDER
		set villagerToMod disciple VILLAGER_DISCIPLE_BUILDER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_BREEDER
		set villagerToMod disciple VILLAGER_DISCIPLE_BREEDER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_PROTECTION
		set villagerToMod disciple VILLAGER_DISCIPLE_PROTECTION with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_MISSIONARY
		set villagerToMod disciple VILLAGER_DISCIPLE_MISSIONARY with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_CRAFTSMAN
		set villagerToMod disciple VILLAGER_DISCIPLE_CRAFTSMAN with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_TRADER
		set villagerToMod disciple VILLAGER_DISCIPLE_TRADER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_CHANGE_HOUSE
		set villagerToMod disciple VILLAGER_DISCIPLE_CHANGE_HOUSE with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_WORSHIP
		set villagerToMod disciple VILLAGER_DISCIPLE_WORSHIP with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_PROTESTOR
		set villagerToMod disciple VILLAGER_DISCIPLE_PROTESTOR with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_RESEARCHER
		set villagerToMod disciple VILLAGER_DISCIPLE_RESEARCHER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_MINER
		set villagerToMod disciple VILLAGER_DISCIPLE_MINER with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_PILGRIM
		set villagerToMod disciple VILLAGER_DISCIPLE_PILGRIM with sound
	elsif discipleType == GE_VILLAGER_DISCIPLE_REFINER
		set villagerToMod disciple VILLAGER_DISCIPLE_REFINER with sound
	end if

	ALTITUDE of rGodInstance = geGodAltitude
end script ge_CreateDisciple


begin script ge_RemoveDisciple(rGodInstance,GodHandle,DiscipleType,TownRadius)
	godHandle = GodHandle
	discipleType = DiscipleType
	villagerToMod = 0
	townRadius = TownRadius
start
	if discipleType == GE_VILLAGER_DISCIPLE_FARMER
		villagerToMod = get disciple VILLAGER_DISCIPLE_FARMER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_FORESTER
		villagerToMod = get disciple VILLAGER_DISCIPLE_FORESTER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_FISHERMAN
		villagerToMod = get disciple VILLAGER_DISCIPLE_FISHERMAN at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_BUILDER
		villagerToMod = get disciple VILLAGER_DISCIPLE_BUILDER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_BREEDER
		villagerToMod = get disciple VILLAGER_DISCIPLE_BREEDER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_PROTECTION
		villagerToMod = get disciple VILLAGER_DISCIPLE_PROTECTION at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_MISSIONARY
		villagerToMod = get disciple VILLAGER_DISCIPLE_MISSIONARY at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_CRAFTSMAN
		villagerToMod = get disciple VILLAGER_DISCIPLE_CRAFTSMAN at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_TRADER
		villagerToMod = get disciple VILLAGER_DISCIPLE_TRADER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_CHANGE_HOUSE
		villagerToMod = get disciple VILLAGER_DISCIPLE_CHANGE_HOUSE at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_WORSHIP
		villagerToMod = get disciple VILLAGER_DISCIPLE_WORSHIP at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_PROTESTOR
		villagerToMod = get disciple VILLAGER_DISCIPLE_PROTESTOR at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_RESEARCHER
		villagerToMod = get disciple VILLAGER_DISCIPLE_RESEARCHER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_MINER
		villagerToMod = get disciple VILLAGER_DISCIPLE_MINER at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_PILGRIM
		villagerToMod = get disciple VILLAGER_DISCIPLE_PILGRIM at {ge_HomeTown[godHandle]} radius townRadius
	elsif discipleType == GE_VILLAGER_DISCIPLE_REFINER
		villagerToMod = get disciple VILLAGER_DISCIPLE_REFINER at {ge_HomeTown[godHandle]} radius townRadius
	end if
	
	if villagerToMod exists
		run script ge_MoveToRadiusAltitude(godHandle,rGodInstance,villagerToMod,geArrivalRadius,gePickupResourceAltitude)
		set villagerToMod disciple VILLAGER_DISCIPLE_NONE with sound
		ALTITUDE of rGodInstance = geGodAltitude
	end if
end script ge_RemoveDisciple


begin script ge_ChargeMana(GodHandle)
	godHandle = GodHandle
start
	while 1 == 1
		wait 1 second
		ge_Mana[godHandle] += ge_ManaPerSecond[godHandle]
	end while
end script ge_ChargeMana


// ## GE VISUAL SCRIPTS IMPLEMENTATION ##
begin script ge_VisualFoodUp(rGodInstance,rTime)
	visualEffect = create visual effect VISUAL_EFFECT_RESOURCE_GRAIN_UP at {rGodInstance}+{0,-2,-3} time rTime
start
	if camera position near {rGodInstance} radius 100.00
		play sound "PICKUPFOOD" at {rGodInstance} with volume 1.0 pitch 0.0
		wait rTime seconds
		stop sound "PICKUPFOOD"
	end if
end script ge_VisualFoodUp

